﻿using Newtonsoft.Json.Linq;
using RuoVea.OmiApi.Dict.Language;

namespace RuoVea.OmiApi.Dict.Service;

/// <summary>
/// 字典值验证器 - 分离 value 格式验证和 extData 必填验证
/// 新的设计思路：
/// 1. value 字段始终必填，根据 tagType 验证特定格式
/// 2. extData 字段仅在特殊类型（image/url/html/json）时必填并验证格式
/// 3. 验证逻辑与前端保持一致，提供清晰的错误信息
/// </summary>
public class SysDictValueValidator
{
    /// <summary>
    /// 定义需要 extData 的特殊类型集合
    /// </summary>
    public readonly HashSet<string> _specialTypes = new HashSet<string>
    {
        "image",     // 图片类型：需要 imageUrl
        "url",       // 链接类型：需要 linkUrl  
        "html",      // HTML类型：需要 content
        "json"       // JSON类型：需要有效的JSON数据
    };

    /// <summary>
    /// 验证 value 字段的格式（根据 tagType 进行特定格式验证）
    /// </summary>
    /// <param name="tagType">标签类型</param>
    /// <param name="value">值内容</param>
    /// <returns>验证结果和错误信息</returns>
    public (bool IsValid, string ErrorMessage) ValidateValueFormat(string tagType, string value)
    {
        if (string.IsNullOrWhiteSpace(tagType))
            return (false, i18n.SelectDisplayType);

        if (string.IsNullOrEmpty(value))
            return (false, i18n.InputValueContent);

        tagType = tagType.ToLower();

        // 根据不同的 tagType 进行特定的格式验证
        return tagType switch
        {
            "progress" => ValidateProgressValue(value),    // 进度条：0-100的整数
            "color" => ValidateColorValue(value),          // 颜色：有效的颜色格式
            "boolean" => ValidateBooleanValue(value),      // 布尔值：true/false/1/0
            "date" => ValidateDateValue(value),            // 日期：有效日期或时间戳
            _ => (true, null)                              // 其他类型：不验证格式
        };
    }

    /// <summary>
    /// 验证 extData 字段（仅在特殊类型时进行必填和格式验证）
    /// </summary>
    /// <param name="tagType">标签类型</param>
    /// <param name="extData">扩展数据</param>
    /// <returns>验证结果和错误信息</returns>
    public (bool IsValid, string ErrorMessage) ValidateExtData(string tagType, string extData)
    {
        if (string.IsNullOrWhiteSpace(tagType))
            return (false, i18n.SelectDisplayType);

        tagType = tagType.ToLower();

        // 非特殊类型，extData 为可选字段，不进行验证
        if (!_specialTypes.Contains(tagType))
            return (true, null);

        if (string.IsNullOrEmpty(extData))
            return (false, i18n.InputExtData);

        // 特殊类型需要验证 extData 的必填性和格式
        return tagType switch
        {
            "image" => (true, null),// ValidateImageExtData(extData),      // 图片类型：验证 imageUrl
            "url" => (true, null),// ValidateUrlExtData(extData),          // 链接类型：验证 linkUrl
            "html" => ValidateHtmlExtData(extData),        // HTML类型：验证 content
            "json" => ValidateJsonExtData(extData),        // JSON类型：验证JSON格式
            _ => (true, null)
        };
    }



    #region Value 格式验证方法

    /// <summary>
    /// 验证进度条类型的值格式（0-100的整数）
    /// </summary>
    private (bool, string) ValidateProgressValue(string value)
    {
        if (!int.TryParse(value, out var percentage) || percentage < 0 || percentage > 100)
            return (false, i18n.ProgressValueRange);

        return (true, null);
    }

    /// <summary>
    /// 验证颜色类型的值格式（支持多种颜色格式）
    /// </summary>
    private (bool, string) ValidateColorValue(string value)
    {
        if (!IsValidColor(value))
            return (false, i18n.ColorFormatError);

        return (true, null);
    }

    /// <summary>
    /// 验证布尔类型的值格式（true/false/1/0）
    /// </summary>
    private (bool, string) ValidateBooleanValue(string value)
    {
        // 支持布尔值和数字表示
        if (!bool.TryParse(value.ToLower(), out _) && !new[] { "1", "0" }.Contains(value))
            return (false, i18n.BooleanFormatError);

        return (true, null);
    }

    /// <summary>
    /// 验证日期类型的值格式（日期字符串或时间戳）
    /// </summary>
    private (bool, string) ValidateDateValue(string value)
    {
        if (!IsValidDate(value))
            return (false, i18n.DateFormatError);

        return (true, null);
    }

    #endregion

    #region ExtData 验证方法

    /// <summary>
    /// 验证图片类型的扩展数据（必须包含有效的imageUrl）
    /// </summary>
    private (bool, string) ValidateImageExtData(string extData)
    {
        if (string.IsNullOrEmpty(extData))
            return (false, i18n.ImageExtDataRequired);

        try
        {
            var imageUrl = GetImageUrlFromExtData(extData);
            if (string.IsNullOrEmpty(imageUrl))
                return (false, i18n.ImageUrlRequired);

            //if (!IsValidUrl(imageUrl))
            //    return (false, "图片URL格式不正确，请输入有效的图片链接地址");

            return (true, null);
        }
        catch
        {
            return (false, i18n.ExtDataFormatError);
        }
    }

    /// <summary>
    /// 验证链接类型的扩展数据（必须包含有效的linkUrl）
    /// </summary>
    private (bool, string) ValidateUrlExtData(string extData)
    {
        if (string.IsNullOrEmpty(extData))
            return (false, i18n.UrlExtDataRequired);

        try
        {
            var linkUrl = GetLinkUrlFromExtData(extData);
            if (string.IsNullOrEmpty(linkUrl))
                return (false, i18n.LinkUrlRequired);

            //if (!IsValidUrl(linkUrl))
            //    return (false, "链接URL格式不正确，请输入有效的网址");

            return (true, null);
        }
        catch
        {
            return (false, i18n.ExtDataFormatError);
        }
    }

    /// <summary>
    /// 验证HTML类型的扩展数据（必须包含content字段）
    /// </summary>
    private (bool, string) ValidateHtmlExtData(string extData)
    {
        if (string.IsNullOrEmpty(extData))
            return (false, i18n.HtmlExtDataRequired);

        try
        {
            var content = GetHtmlContentFromExtData(extData);
            if (string.IsNullOrEmpty(content))
                return (false, i18n.HtmlContentRequired);

            return (true, null);
        }
        catch
        {
            return (false, i18n.ExtDataFormatError);
        }
    }

    /// <summary>
    /// 验证JSON类型的扩展数据（必须是有效的JSON格式）
    /// </summary>
    private (bool, string) ValidateJsonExtData(string extData)
    {
        if (string.IsNullOrEmpty(extData))
            return (false, i18n.JsonExtDataRequired);

        try
        {
            JToken.Parse(extData); // 使用JToken支持任何JSON格式（对象、数组、简单值）
            return (true, null);
        }
        catch
        {
            return (false, i18n.JsonFormatError);
        }
    }

    #endregion

    #region 辅助方法

    /// <summary>
    /// 从扩展数据中提取图片URL
    /// </summary>
    private string GetImageUrlFromExtData(string extData)
    {
        var parsed = ParseExtData(extData);
        return GetValueFromDynamic(parsed, "imageUrl", "");
    }

    /// <summary>
    /// 从扩展数据中提取链接URL
    /// </summary>
    private string GetLinkUrlFromExtData(string extData)
    {
        var parsed = ParseExtData(extData);
        return GetValueFromDynamic(parsed, "linkUrl", "");
    }

    /// <summary>
    /// 从扩展数据中提取HTML内容
    /// </summary>
    private string GetHtmlContentFromExtData(string extData)
    {
        var parsed = ParseExtData(extData);
        return GetValueFromDynamic(parsed, "content", "");
    }

    /// <summary>
    /// 验证颜色格式是否有效
    /// </summary>
    private bool IsValidColor(string color)
    {
        if (color.StartsWith("#"))
        {
            // 支持 #RGB 和 #RRGGBB 格式
            return color.Length == 4 || color.Length == 7;
        }

        if (color.StartsWith("rgb(") && color.EndsWith(")"))
            return true;

        if (color.StartsWith("rgba(") && color.EndsWith(")"))
            return true;

        // 支持常见的颜色名称
        var colorNames = new[] { "red", "blue", "green", "black", "white", "yellow", "orange", "purple", "pink", "gray", "brown" };
        return colorNames.Contains(color.ToLower());
    }

    /// <summary>
    /// 验证日期格式是否有效
    /// </summary>
    private bool IsValidDate(string dateStr)
    {
        // 尝试解析为DateTime
        if (DateTime.TryParse(dateStr, out _))
            return true;

        // 尝试解析为时间戳（long类型）
        return long.TryParse(dateStr, out var timestamp) && timestamp > 0;
    }

    ///// <summary>
    ///// 验证URL格式是否有效
    ///// </summary>
    //private bool IsValidUrl(string url)
    //{
    //    return Uri.TryCreate(url, UriKind.Absolute, out _);
    //}

    /// <summary>
    /// 解析ExtData字符串为动态对象
    /// </summary>
    private dynamic ParseExtData(string extData)
    {
        if (string.IsNullOrEmpty(extData)) return null;

        try
        {
            return JObject.Parse(extData);
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 从动态对象中获取指定键的值
    /// </summary>
    private T GetValueFromDynamic<T>(dynamic obj, string key, T defaultValue)
    {
        if (obj == null) return defaultValue;

        try
        {
            if (obj is JObject jObject)
            {
                var value = jObject[key];
                return value != null ? value.ToObject<T>() : defaultValue;
            }
            return defaultValue;
        }
        catch
        {
            return defaultValue;
        }
    }

    #endregion
}